package com.easylinkin.linkappapi.progress.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.building.entity.dto.BuildingTreeDTO;
import com.easylinkin.linkappapi.building.service.BuildingService;
import com.easylinkin.linkappapi.progress.entity.ProgressImage;
import com.easylinkin.linkappapi.progress.entity.dto.ProgressImageTreeDTO;
import com.easylinkin.linkappapi.progress.entity.vo.ProgressImageSetVo;
import com.easylinkin.linkappapi.progress.entity.vo.ProgressImageVo;
import com.easylinkin.linkappapi.progress.mapper.ProgressImageMapper;
import com.easylinkin.linkappapi.progress.service.ProgressImageService;
import com.easylinkin.linkappapi.progress.service.ProgressImageSetService;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Collectors;

/**
 * <p>
 * 形象进度
 * </p>
 *
 * @author kanyuanfeng
 * @since 2023-04-13
 */
@Service
public class ProgressImageServiceImpl extends ServiceImpl<ProgressImageMapper, ProgressImage> implements ProgressImageService {

  @Autowired
  private LinkappUserContextProducer linkappUserContextProducer;
  @Autowired
  private BuildingService buildingService;
  @Autowired
  private ProgressImageSetService progressImageSetService;

  /**
   * 增加
   * @param progressImage
   */
  @Override
  public void insert(ProgressImage progressImage) {
    this.saveOrUpdate(progressImage,(t) -> save(t));
  }

  /**
   * 根据id编辑
   * @param progressImage
   */
  @Override
  public void updateOne(ProgressImage progressImage) {
    this.saveOrUpdate(progressImage,(t) -> updateById(t));
  }

  /**
   * @Description: 查询形象进度列表
   * @author kan yuanfeng
   * @date 2023/04/04 11:42
   */
  @Override
  public List<ProgressImageTreeDTO> queryList() {
//    List<BuildingTreeDTO> treeDTOS = buildingService.tree();
    List<BuildingTreeDTO> treeDTOS = new ArrayList<>();
    //转换为形象进度树
    List<ProgressImageTreeDTO> progressImageTreeDTOS = toConvert(treeDTOS);

    //查询显示的属性
    List<ProgressImageSetVo> imageSetVos = progressImageSetService.queryList();
    List<String> showCodes = imageSetVos.stream().filter(i -> Integer.valueOf(1).equals(i.getIsShow())).map(i -> i.getCode()).collect(Collectors.toList());

    imageSetVos.removeIf(i->!Integer.valueOf(1).equals(i.getIsShow()));
    //查询形象进度
    LambdaQueryWrapper<ProgressImage> lambdaQueryWrapper = new LambdaQueryWrapper<>();
    lambdaQueryWrapper.eq(ProgressImage::getTenantId,linkappUserContextProducer.getCurrent().getTenantId());
    List<ProgressImage> progressImages = baseMapper.selectList(lambdaQueryWrapper);
    progressImages.removeIf(p->!showCodes.contains(p.getCode()));

    List<ProgressImageVo> progressImageVos = BeanUtil.copyToList(progressImages, ProgressImageVo.class);

    //按code分组
    Map<String, List<ProgressImageVo>> listMap = progressImageVos.stream().collect(Collectors.groupingBy(p -> p.getCode()));

    progressImageTreeDTOS.forEach(tree ->{
      //父节点
      setAllProgress(imageSetVos, listMap, tree,1);
      //子节点
      if (CollectionUtil.isNotEmpty(tree.getChildren())){
        tree.getChildren().forEach(c->
          setAllProgress(imageSetVos, listMap, c,2)
        );
      }
    });
    return progressImageTreeDTOS;
  }

  /**
   * 增加
   * @param progressImages
   */
  @Override
  public void insertList(List<ProgressImage> progressImages) {
    String tenantId = linkappUserContextProducer.getCurrent().getTenantId();
    progressImages.forEach(p ->{
    //查询是否存在
    LambdaQueryWrapper<ProgressImage> lambdaQueryWrapper = new LambdaQueryWrapper<>();
    lambdaQueryWrapper.eq(ProgressImage::getTenantId,tenantId)
            .eq(ProgressImage::getCode,p.getCode())
            .eq(ProgressImage::getType,p.getType())
            .eq(ProgressImage::getBuildingFloorId,p.getBuildingFloorId());
      List<ProgressImage> images = baseMapper.selectList(lambdaQueryWrapper);
      if (CollectionUtil.isNotEmpty(images)){
        p.setId(images.get(0).getId());
      }
      if (null != p.getId()){
        this.saveOrUpdate(p,(t) -> updateById(t));
      }else {
        this.saveOrUpdate(p,(t) -> insert(t));
      }
    });
  }


  private void setAllProgress(List<ProgressImageSetVo> imageSetVos, Map<String, List<ProgressImageVo>> listMap, ProgressImageTreeDTO tree,Integer type) {
    List<ProgressImageVo> progress = new ArrayList<>();
    imageSetVos.forEach(i ->{
      List<ProgressImageVo> progressImageVos = listMap.get(i.getCode());
      //父节点
      ProgressImageVo imageVo = setProgress(i, progressImageVos, tree);
      imageVo.setEditFlag(type.equals(i.getComputeType()));
      //子节点
      if (!Integer.valueOf(1).equals(i.getComputeType()) && CollectionUtil.isNotEmpty(tree.getChildren())){
        List<ProgressImageVo> sProgress = new ArrayList<>();
        tree.getChildren().forEach(c->{
          ProgressImageVo childImageVo = setProgress(i, progressImageVos, c);
          sProgress.add(childImageVo);
        });
        //求值
        double sum = sProgress.stream().mapToDouble(s -> s.getProgress()).sum();
        //求平均值，并且保留两位小数
        double aDouble = Double.parseDouble(new DecimalFormat("#.00").format(sum / Double.valueOf(sProgress.size())));
        imageVo.setProgress(aDouble);
      }
      progress.add(imageVo);
    });
    tree.setProgress(progress);
  }

  /**
   * 设置进度
   * @param tree
   */
  private ProgressImageVo setProgress(ProgressImageSetVo imageSetVo, List<ProgressImageVo> progressImageVos, ProgressImageTreeDTO tree) {
    ProgressImageVo imageVo = new ProgressImageVo(imageSetVo.getCode(), imageSetVo.getName(), 0d);
    if (CollectionUtil.isNotEmpty(progressImageVos)){
      imageVo = progressImageVos.stream().filter(p -> p.getType().equals(tree.getType()) && p.getBuildingFloorId().equals(tree.getId()))
              .findFirst().orElse(new ProgressImageVo(imageSetVo.getCode(), imageSetVo.getName(), 0d));
    }
    return imageVo;
  }

  /**
   * 转换为形象进度树
   * @param treeDTOS
   * @return
   */
  private List<ProgressImageTreeDTO> toConvert(List<BuildingTreeDTO> treeDTOS) {
    //转换为形象进度树
    List<ProgressImageTreeDTO> list = new ArrayList<>();
    treeDTOS.forEach(t -> {
      ProgressImageTreeDTO imageTreeDTO = this.convertTree(t);
      if (CollectionUtil.isNotEmpty(t.getChildren())){
        List<ProgressImageTreeDTO> progressImageTreeDTOS = toConvert(t.getChildren());
        imageTreeDTO.setChildren(progressImageTreeDTOS);
      }
      list.add(imageTreeDTO);
    });
    return list;
  }

  /**
   * 转换
   */
  private ProgressImageTreeDTO convertTree(BuildingTreeDTO treeDTO) {
    //转换为形象进度树
    ProgressImageTreeDTO progressImageTreeDTO = new ProgressImageTreeDTO();
    progressImageTreeDTO.setName(treeDTO.getLabel());
    String value = treeDTO.getValue();
    if (StringUtils.isNotBlank(value)){
      String[] split = value.split("-");
      progressImageTreeDTO.setType(Integer.valueOf(split[0]));
      progressImageTreeDTO.setId(Integer.valueOf(split[1]));
    }
    return progressImageTreeDTO;
  }

  /**
   * 执行新增和更新
   * @param progressImage
   * @param consumer 自定义执行
   */
  private void saveOrUpdate(ProgressImage progressImage, Consumer<ProgressImage> consumer) {
    //设置基本属性
    this.setBase(progressImage);
    consumer.accept(progressImage);
  }

  /**
   * 设置基本属性
   * @param progressImage
   */
  private void setBase(ProgressImage progressImage) {
    Long userId = null;
    if(null != linkappUserContextProducer.getCurrent()){
      userId = linkappUserContextProducer.getCurrent().getId();
    }
    progressImage.setModifyTime(new Date());
    progressImage.setModifyId(userId);
    //没有id就是新增,有就是编辑
    if (null == progressImage.getId()){
        if (StringUtils.isBlank(progressImage.getTenantId())){
          progressImage.setTenantId(linkappUserContextProducer.getNotNullCurrent().getTenantId());
        }
      progressImage.setCreatorId(userId);
      progressImage.setCreateTime(new Date());
    }
  }
}
